package ensemble.pages

import net.oschina.oldpig.snout.FxBuilder._
import javafx.scene.control.ContentDisplay
import javafx.scene.web.{WebEngine, WebView}
import ensemble.{EnsembleSample, Ensemble2Controller, Ensemble2View}
import scala.collection.mutable
import javafx.scene.layout.Priority
import javafx.event.ActionEvent
import java.net.URL
import ensemble.controls.SimplePropertySheet

case class SampleInfo(sourceFileUrl: URL, unqualifiedClassName: String, fileContent: String) {
  val name = Ensemble2Controller.formatName(unqualifiedClassName)
  val packageName = SampleInfo.findPackage.findFirstMatchIn(fileContent).get.group(1)
  val className = {
    packageName + "." + unqualifiedClassName
  }
  val ensemblePath = {
    val path = "/" + packageName.substring("ensemble.samples.".length).split("\\.").mkString("/")
    Pages.SAMPLES + path + "/" + name
  }
  val javaDocComment = SampleInfo.findJavaDocComment.findFirstMatchIn(fileContent).get.group(1)
  val relatedList = mutable.Buffer.empty[String]
  val seeList = mutable.Buffer.empty[String]
  val resourceList = mutable.Buffer.empty[String]
  val descBuilder = new StringBuilder
  for (jdocLine <- javaDocComment.split("([ \\t]*\\n[ \\t]*\\*[ \\t]*)+")) {
    val trimedLine = jdocLine.trim
    if (trimedLine.nonEmpty) {
      if (trimedLine.startsWith("@related")) {
        relatedList += trimedLine.substring("@related".length).trim
      } else if (trimedLine.startsWith("@related")) {
        seeList += trimedLine.substring("@related".length).trim
      } else if (trimedLine.startsWith("@resource")) {
        resourceList += trimedLine.substring("@resource".length).trim
      } else {
        descBuilder.append(trimedLine).append(' ')
      }
    }
  }
  val description = descBuilder.toString()
  val relatesSamplePaths = relatedList.toArray
  val apiClasspaths = seeList.toArray
  val resourceUrls = resourceList.toArray
}

object SampleInfo {
  val findPackage = "[ \\t]*package[ \\t]*([^;]*);\\s*".r
  val findJavaDocComment = "\\/\\*\\*(.*?)\\*\\/\\s*".r
}

/**
 *
 * @param name SomeSample => Some Sample
 * @param qualifiedClass 形如 com.gtan.SomeSample
 */
case class SamplePage(override val name: String, qualifiedClass: String) extends Page(name) {
  /*
  val sampleInfo = {
    val sourceFileUrl = getClass.getClassLoader.getResource(qualifiedClass.replaceAll("\\.", "/")+".scala")
    val unqualifiedClassName = qualifiedClass.split('.').last //sourceFileUrl.substring(sourceFileUrl.lastIndexOf('/') + 1, sourceFileUrl.length - ".class".length + 1)
    SampleInfo(sourceFileUrl, unqualifiedClassName, name)
//    SampleInfo(sourceFileUrl, unqualifiedClassName, io.Source.fromURL(sourceFileUrl).mkString)
  }
  for (apiClassPath <- sampleInfo.apiClasspaths) {
    val path = Pages.API_DOCS + "/" + apiClassPath.replace('.', '/')
    val docPage = Pages.getPage(path).asInstanceOf[DocPage]
    if (docPage != null)
      docPage.relatedSamples.add(this)
  }
  */
  val sampleClass = getClass.getClassLoader.loadClass(qualifiedClass)

  override def createView = {
    val sample = is[EnsembleSample]
    tabPane(id := "source-tabs") {
      tab(text := "Sample", closable := false) {
        scrollPane(styleClass := "noborder-scroll-pane", fitToWidth := true, fitToHeight := true, minWidth := 725) {
          borderPane() {
            center := vBox(spacing := 8, styleClass := "sample-page") {
              label(text := name, styleClass := "page-header")
              stackPane(vBox.vgrow := Priority.SOMETIMES) {
                adopt(sampleClass.newInstance.asInstanceOf[EnsembleSample] as sample)
              }
              if (sample.controls.nonEmpty) {
                label(text := "Play with these:", styleClass := "page-subheader")
                adopt(new SimplePropertySheet(sample.controls: _*))
              }
            }
            right := createSideBar(sample)
          }
        }
      }
      tab(text := "Source Code", closable := false) {
        borderPane() {
          top := toolBar(id := "code-tool-bar") {
            button(text := "Save Netbeans Project...", onAction := onSaveProject)
            button(text := "Copy Source", onAction := onCopyCode)
          }
          center := SamplePage.webView
        }
      }
    }
  }

  def createSideBar(sample: EnsembleSample) = gridPane(styleClass := "right-sidebar", maxWidth := Double.MaxValue, maxHeight := Double.MaxValue) {
    label(text := "Description", styleClass := "right-sidebar-title", gridPane.constraints :=(0, 1))
    //    fxText(text := sampleInfo.description, wrappingWidth := 200, styleClass:="right-sidebar-body", gridPane.constraints := (0, 2))
  }

  private def onSaveProject(e: ActionEvent): Unit = {

  }

  private def onCopyCode(e: ActionEvent): Unit = {

  }

  def createTile = button(text := name.trim, minSize :=(140, 145), prefSize :=(140, 145), maxSize :=(140, 145),
    contentDisplay := ContentDisplay.TOP, styleClass := "sample-tile", onAction := { _ =>
      Ensemble2View.gotoPage(this)
    })

  def getIcon = {

  }

}

object SamplePage {
  lazy val webView: WebView = new WebView
  lazy val engine: WebEngine = {
    webView.setContextMenuEnabled(false)
    webView.getEngine
  }

  //  def clone(src: SamplePage): SamplePage = new SamplePage(src.name, src.sourceFileUrl) {
  //    override val sampleInfo = src.sampleInfo
  //    override val sampleClass = src.sampleClass
  //  }

  def getSamples(rootPage: CategoryPage) {

  }
}


